package com.lhl.security.filter;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.lhl.security.domain.User;
import com.lhl.security.mapper.RoleMapper;
import com.lhl.security.service.UserService;
import com.lhl.security.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    private final UserService userService;
    private final RoleMapper roleMapper;
    private final RedisTemplate<String, String> redisTemplate;

    public JwtAuthenticationTokenFilter(RoleMapper roleMapper, UserService userService, RedisTemplate<String, String> redisTemplate) {
        this.roleMapper = roleMapper;
        this.userService = userService;
        this.redisTemplate = redisTemplate;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) throws ServletException, IOException {
        //获取token
        String token = req.getHeader("Authorization");
        if (!StringUtils.hasText(token)) {
            filterChain.doFilter(req, res);
            return;
        }
        //解析token
        String userid = null;
        try {
            Claims claims = JwtUtils.parseJWT(token);
            userid = claims.getSubject();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("token非法！");
        }
        String key = "USER::" + userid;

        Boolean b = redisTemplate.hasKey(key);
        if (Boolean.TRUE.equals(b)) {
            String s = redisTemplate.opsForValue().get(key);
            UsernamePasswordAuthenticationToken authenticationToken = JSONObject.parseObject(s, UsernamePasswordAuthenticationToken.class);
            System.out.println(JSONObject.toJSONString(authenticationToken));
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        } else {
            //通过token解析出来的id查找用户
            User user = userService.getById(userid);
            if (ObjectUtils.isNull(user)) {
                System.out.println("无用户！");
            }
            //获取用户的权限
            user.setRoles(roleMapper.getRoleListByUserId(user.getId()));
            //把信息填入 AuthenticationToken 实现类中填入  用户、证书、权限
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(user, token, user.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);

            String jsonString = JSONObject.toJSONString(authenticationToken);
            System.out.println(jsonString);
            redisTemplate.opsForValue().set(key, jsonString);
            redisTemplate.expire(key, 3600, TimeUnit.SECONDS);
        }
        //放行
        filterChain.doFilter(req, res);
    }
}
